/*
 * Tablero 7 posiciones con con tres fichas negras a las izquierda, 3 blancas
 * a la derecha y un hueco entre medias, consiste en acabar el juego con las
 * 3 fichas blancas a la izquierda y las 3 fichas negras a la derecha.
 * Cada ficha solo puede moverse en el sentido correspondiente a su color(negras solo
 * de izquierda a derecha y blancas de derecha a izquierda) y los movientos permitidos
 * son los siguientes: Avanzar si la casilla de delante está vacía, saltar una fich
 * q se tenga delante(el color no importa), si esta tiene a si vez un hueco vacío delante

 * estado(posHue,negra1,negra2,negra3)

 * posHue, sera las posiciones de 0..6
 * negras1,negras2,negras3 indica la posicion de las fichas negras, asi ya tenemos
 * la situación de todos los elementos del tablero
 *
 * estado inical (3,0,1,2)
 * estados objetivo (3,4,5,6),(3,4,6,5),(3,5,6,4),(3,5,4,6),(3,6,5,4),(3,6,4,5)
 */

package Problemas;
import Busquedas.Estado;
/**
 *
 *
 */
public class IntercambioTablero extends Problema {

    private int posHue;
    private int negra1;
    private int negra2;
    private int negra3;

    public IntercambioTablero (){

        int[] paramInicial={3,0,1,2};
		int[] paramObjetivo = {3,4,5,6};
        int[] paramObjetivo1 = {3,4,6,5};
        int[] paramObjetivo2 = {3,5,6,4};
        int[] paramObjetivo3 = {3,5,4,6};
        int[] paramObjetivo4 = {3,6,5,4};
        int[] paramObjetivo5 = {3,6,4,5};
        Estado inicial = new Estado(paramInicial);
		Estado [] objetivo = new Estado[6];
		objetivo[0] = new Estado(paramObjetivo);
        objetivo[1] = new Estado(paramObjetivo1);
        objetivo[2] = new Estado(paramObjetivo2);
        objetivo[3] = new Estado(paramObjetivo3);
        objetivo[4] = new Estado(paramObjetivo4);
        objetivo[5] = new Estado(paramObjetivo5);
        String [] nombresOperadores={"padre","moverNDer","moverNSaltaDer","moverBIzq","moverBSaltaIz"};

        //Saltar una ficha cuesta 2 ya q mueves 2 posiciones
        int [] costeOperadores={1,2,1,2};
		inicializa(inicial,objetivo,4,nombresOperadores,costeOperadores);

    }

    public void asignaParametros(Estado actual){
		posHue = actual.getParametro(0);
		negra1 = actual.getParametro(1);
		negra2 = actual.getParametro(2);
        negra3 = actual.getParametro(3);
	}

    public Estado moverNDer(Estado actual){
        Estado siguiente= null;
        if ( posHue>0 && negra1 == posHue-1){
            int param[] = {posHue-1,negra1+1,negra2,negra3};
			siguiente = new Estado(param);
	    }else if ( posHue>0 && negra2 == posHue-1){
            int param[] = {posHue-1,negra1,negra2+1,negra3};
			siguiente = new Estado(param);
	    }else if ( posHue>0 && negra3 == posHue-1){
            int param[] = {posHue-1,negra1,negra2,negra3+1};
			siguiente = new Estado(param);
        }
       return siguiente;
    }

    public Estado moverNSaltaDer(Estado actual){
        Estado siguiente= null;
        if ( posHue>1 && negra1 == posHue-2){
            int param[] = {posHue-2,negra1+2,negra2,negra3};
			siguiente = new Estado(param);
	    }else if ( posHue>1 && negra2 == posHue-2){
            int param[] = {posHue-2,negra1,negra2+2,negra3};
			siguiente = new Estado(param);
	    }else if ( posHue>1 && negra3 == posHue-2){
            int param[] = {posHue-2,negra1,negra2,negra3+2};
			siguiente = new Estado(param);
        }
       return siguiente;
    }

    public Estado moverBIzq(Estado actual){
        Estado siguiente= null;
        if ( posHue<6 && negra1 != posHue+1 && negra2 != posHue+1 && negra3 != posHue+1){
            int param[] = {posHue+1,negra1,negra2,negra3};
			siguiente = new Estado(param);
	   }
       return siguiente;
    }

    public Estado moverBSaltaIz(Estado actual){
        Estado siguiente= null;
        if ( posHue<5 && negra1 != posHue+2 && negra2 != posHue+2 && negra3 != posHue+2){
            int param[] = {posHue+2,negra1,negra2,negra3};
			siguiente = new Estado(param);
	   }
       return siguiente;
    }
   	public Estado aplicaOperador(Estado actual,int i){
		asignaParametros(actual);
        Estado siguiente = null;
		switch(i){
		case 0:
			siguiente = moverNDer(actual);
			break;
		case 1:
			siguiente =moverNSaltaDer(actual);
			break;
		case 2:
			siguiente = moverBIzq(actual);
            break;
        case 3:
            siguiente =  moverBSaltaIz(actual);
		}
		return siguiente;
	}
    public int funcionHeuristica(Estado estado){

//h = " nº de fichas blancas a la derecha de alguna ficha negra" + la distancia al centro del hueco
       asignaParametros(estado);
       int blanca1 = 0,blanca2=0,blanca3=0;
       int i=0;
       boolean fin=false;
       while (i<7&&!fin){
           if(i!=negra1&&i!=negra2&&i!=negra3&&i!=posHue){
               fin=true;
               blanca1=i;
           }
            i++;
       }
       fin=false;
       while (i<7&&!fin){
           if(i!=negra1&&i!=negra2&&i!=negra3&&i!=posHue){
               fin=true;
               blanca2=i;
           }
               i++;
       }
       fin=false;
       while (i<7&&!fin){
           if(i!=negra1&&i!=negra2&&i!=negra3&&i!=posHue){
               fin=true;
               blanca3=i;
           }
               i++;
       }
       int aux=(int)Math.min(negra1,(int)Math.min(negra2,negra3));
       int aux2=0;
       if (aux<blanca1) aux2++;
       if (aux<blanca2) aux2++;
       if (aux<blanca3) aux2++;
       aux2= aux2 + (int)Math.abs(3-posHue);
       return aux2;
	}


    public int getOperadorInverso(int op){


        return -1;
	}

}
